package cc.sends;

import java.util.ArrayList;
import java.util.List;

/**
 * @ Description : LRU Algorithm
 * @ Author : ChristosC
 * @ Date : 2020/12/15 17:32
 */
public class LRU {
    private int ramSize;
    private int requestPageQueueSize;
    private int missTime = 0;
    private float missRate = 0;
    private List<Page> ramQueue;
    private List<Page> requestPageQueue;

    public void init(List<Page> requestPageQueue, int ramSize, int requestPageQueueSize){
        this.requestPageQueueSize = requestPageQueueSize;
        this.ramSize = ramSize;
        this.ramQueue = new ArrayList();
        this.requestPageQueue = requestPageQueue;
    }

    public void start(){
        Page currPage;
        Page pageToReplace;
        int pageToReplaceIndexInRam;
        do{
            // 取出队头
            currPage = requestPageQueue.get(0);
            // 若 currPage 不在 ramQueue 中
            if(!ramQueueContains(currPage)){
                // 内存块满,主要置换逻辑
                if(ramQueueFull()){
                    missTime++;
                    // 替换 ramQueue 上最老的 Page
                    pageToReplace = getTheOldestPage();
                    pageToReplaceIndexInRam = getPageIndexInRam(pageToReplace);
                    System.out.print("替换"+pageToReplace.getNum()+"后：");
                    ramQueue.get(pageToReplaceIndexInRam).setNum(currPage.getNum());
                    for(Page page : ramQueue){
                        System.out.print(page.getNum()+" ");
                    }
                    System.out.println();
                }else {
                    // 内存块未满直接加入内存块
                    ramQueue.add(currPage);
                    System.out.print("直接加入：");
                    for(Page page : ramQueue){
                        System.out.print(page.getNum()+" ");
                    }
                    System.out.println();
                }
            }
            // 去除队头
            requestPageQueue.remove(0);
            // 更新ramQueue中的page的age
            upDateAge(currPage);

        }
        while (requestPageQueue.size()>0);
        System.out.println("缺页数："+missTime);
        missRate = (float)missTime/requestPageQueueSize;
        System.out.println("缺页率："+missRate);
    }
    private boolean ramQueueFull(){
        return ramQueue.size() == ramSize;
    }
    private boolean ramQueueContains(Page currPage){
        boolean result = false;
        for(Page page : ramQueue){
            if(currPage.getNum() == page.getNum()){
                result = true;
            }
        }
        return result;
    }
    private Page getTheOldestPage(){
        Page oldestPage = new Page(0,0);
        for(Page page : ramQueue){
            if(page.getAge()>oldestPage.getAge()){
                oldestPage.setAge(page.getAge());
                oldestPage.setNum(page.getNum());
            }
        }
        return oldestPage;
    }
    private void upDateAge(Page currPage){
        for(Page page : ramQueue){
            // ramQueue中的page再次被访问的话将其age置为0
            if(page.getNum() == currPage.getNum()){
                page.setAge(0);
            }else {
                // 否则 age 加一
                page.setAge(page.getAge()+1);
            }

        }
    }
    private int getPageIndexInRam(Page pageToReplace){
        int result = 0;
        int i = 0;
        for(Page page : ramQueue){
            if(page.getNum() == pageToReplace.getNum()){
                result = i;
                break;
            }
            i++;
        }
        return result;
    }

}
